ホームに戻る
出典 :
関連 :
目次 :
※当記事は書きかけです。
ReactiveProperty ( Reactive.Bindings.ReactiveProperty )とは
WPFにおいて、リアクティブプログラミング( View / ViewModel の変更を他方に伝播させる)を容易に実現することを目論んで作られたクラス群。
データバインディングやコマンドを簡便に実装することができる。
ReactiveProperty 誕生の背景
データバインディングにおいて、単にソースとターゲットを関連付けるだけではソースの変更がターゲットに反映されない。
従来は INotifyPropertyChanged インタフェースを実装することでこの問題を解決していたが、この実装は煩雑である。
(詳細は出典元ページを参照。)
このため簡便な手順でデータバインディングを実現できる ReactiveProperty が開発された。
関連するクラス
プロパティ、コマンドとも「軽量」に印のあるものは、基のクラスと比較して高速でメモリ効率が良いため、特段の事情が無ければこれらを用いるのが良い。
プロパティ
クラス名 |
読み書き |
軽量 |
検証 |
解説 |
ReactiveProperty<T>
| ○ |
|
|
基本となるプロパティクラス。Value プロパティから値の取得・更新が可能。 |
ReadOnlyReactiveProperty<T>
| |
|
|
読み取り専用の ReactiveProperty 。Value プロパティから値の取得が可能。 |
ReactivePropertySlim<T> |
○ |
○ |
|
軽量化された ReactiveProperty 。 |
ReadOnlyReactivePropertySlim<T>
| |
○ |
|
軽量化された ReadOnlyReactiveProperty 。 |
ValidatableReactiveProperty<T>
| ○ |
○ |
○ |
入力された T に対するバリデーション(検証)を行える。 |
ReactiveCollection<T>
| ○ |
|
|
コレクションを格納し、追加、変更、削除が行える。 |
ReadOnlyReactiveCollection<T>
| |
|
|
読み取り専用の ReactiveCollection。 |
コマンド
クラス名 |
引数 |
軽量 |
非同期 |
タイマ |
Subscribe |
解説 |
ReactiveCommand |
|
|
|
|
Action |
引数を取らないコマンド。 |
ReactiveCommand<T> |
○ |
|
|
|
Action<T> |
引数を取るコマンド。 |
ReactiveCommandSlim |
|
○ |
|
|
Action |
軽量化された ReactiveCommand 。 |
ReactiveCommandSlim<T> |
○ |
○ |
|
|
Action<T> |
軽量化された ReactiveCommand<T> 。 |
AsyncReactiveCommand |
|
○ |
○ |
|
Func<Task> または async void |
コマンドに設定した非同期メソッドが完了するまで 次回のコマンドが実行できなくなる。 |
AsyncReactiveCommand |
○ |
○ |
○ |
|
Func<T, Task> |
引数を取る AsyncReactiveCommand 。 |
ReactiveTimer |
|
|
|
○ |
Action<T> |
停止、再開が可能なタイマクラス。 Subscribe の引数 T にはタイマの発火回数が渡される。 |
非同期に対応するものは、コマンド実行中は自動的に CanExecute を false に設定するため、ボタンの二度押しなどを防ぐことができる。
ReactiveProperty の導入
使用する際は、NuGetから ReactiveProperty パッケージを取得する。
バージョン4.1.0以降は Slim 版が同梱されている。
実装例
ReactivePropertySlim
ReactiveProperty も同様の記述となる。
ViewModel : SampleViewModel.cs
using Reactive.Bindings; // ReactivePropertySlim を使用するための参照
// データソース用クラス
public class SampleViewModel
{
// バインディングソース Count を ReactivePropertySlim として宣言
// 初期値に 0 を指定
public readonly ReactivePropertySlim<int> Count { get; }
= new ReactivePropertySlim<int>(0);
}
View(XAML) : MainWindow.xaml
<Window>
(略)
<!-- DataContext の指定 -->
<Window.DataContext>
<local:SampleViewModel />
</Window.DataContext>
<StackPanel>
<!-- TextBlock の Text を DataContext の Count に関連付け -->
<TextBlock Text="{Binding Path=Count.Value}"/>
<Button Click="CountUp_Click" Content="Count Up!"/>
</StackPanel>
</Window>
View(コードビハインド) : MainWindow.xaml.cs
public partial class MainWindow : Window
{
// コンストラクタ
public MainWindow()
{
InitializeComponent();
}
// ボタン「Count Up!」クリック時の処理
private void CountUp_Click(object sender, RoutedEventArgs e)
{
( (SampleViewModel)DataContext ).Count.Value++;
}
}
ReactiveProperty の各クラスはジェネリクスであり、任意の型を実データとして用いることができる。
上記の例では、実データが int 型の Count プロパティを ReactivePropertySlim として宣言している。コンストラクタは複数のオーバーロードが存在し、実データの初期値を設定することが可能である。
ここで実データは Value プロパティを介してアクセスすることに注意( Count ではなく Count.Value )。
ReactiveCollection
複数のデータを一覧で表示する「リスト系コントロール」のデータを扱うのに適している。
( ReactiveProperty にもコレクション(配列を含む)を格納することは可能ではあるが、項目の追加、変更、削除を行った際に通知を発することができない。
これは、実データ(監視対象)のコレクションそのものが変更されたわけではないことによる。)
主な「リスト系コントロール」は以下が挙げられる。いずれも System.Windows.Controls.ItemsControl を継承している。
- ListBox
- ComboBox
- TreeView
- ListView
- DataGrid
ViewModel : SampleViewModel.cs